package com.stlm2.dems.util;


import com.stlm2.dems.dao.FmsFlowDao;
import com.stlm2.dems.dao.SeckillGoodsDao;
import com.stlm2.dems.entity.FlowSource;
import com.stlm2.dems.entity.FlowType;
import com.stlm2.dems.entity.FmsFlow;
import com.stlm2.dems.entity.SeckillGoods;
import com.stlm2.dems.user.dao.AccountDao;
import com.stlm2.dems.user.entity.Account;
import com.stlm2.dems.user.entity.AccountType;
import com.sun.tools.javac.comp.Flow;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Date;

@Component
public class CoreLogic {
    @Resource
    private AccountDao accountDao;
    @Resource
    private FmsFlowDao fmsFlowDao;
    @Resource
    private SeckillGoodsDao seckillGoodsDao;

    public boolean changeRemainJiFen(Integer ownerId, BigDecimal counts, FlowSource fundsSource, FlowType fundsChangeType) {
        if (ownerId <= 0 || fundsChangeType == null || fundsSource == null)
            return false;
        Account temp = accountDao.getByOwnerId(ownerId);
        if (temp == null)
            return false;
        Account account = null;

        boolean mysqlLockException = false;
        do {
            mysqlLockException = false;
            try {
                account = accountDao.getByIdForUpdate(temp.getId());//数据库加悲观锁，保证不会产生脏读
            } catch (org.springframework.dao.CannotAcquireLockException e) {
                mysqlLockException = true;
            }
        } while (mysqlLockException);


        synchronized (account) {
            //处理资金账户现金量
            if (FlowType.Add.equals(fundsChangeType))
                account.setRemainJiFen(counts.add(account.getAccountMoney()));
            else if (FlowType.Reduce.equals(fundsChangeType)) {
                if (account.getRemainJiFen().compareTo(counts) == -1)
                    return false;

                account.setRemainJiFen(account.getAccountMoney().subtract(counts));
            }

            accountDao.modify(account);

            return true;
        }
    }

    public boolean changeMoneyAccount(Integer ownerId, BigDecimal counts, FlowSource fundsSource, FlowType fundsChangeType) {
        if (ownerId <= 0 || fundsChangeType == null || fundsSource == null)
            return false;
        Account temp = accountDao.getByOwnerId(ownerId);
        if (temp == null)
            return false;
        Account account = null;

        boolean mysqlLockException = false;
        do {
            mysqlLockException = false;
            try {
                account = accountDao.getByIdForUpdate(temp.getId());//数据库加悲观锁，保证不会产生脏读
            } catch (org.springframework.dao.CannotAcquireLockException e) {
                mysqlLockException = true;
            }
        } while (mysqlLockException);


        synchronized (account) {
            //处理资金账户现金量
            if (FlowType.Add.equals(fundsChangeType))
                account.setAccountMoney(counts.add(account.getAccountMoney()));
            else if (FlowType.Reduce.equals(fundsChangeType)) {
                if (account.getAccountMoney().compareTo(counts) == -1)
                    return false;

                account.setAccountMoney(account.getAccountMoney().subtract(counts));
            }

            accountDao.modify(account);

            return true;
        }
    }
    public void addFundsFlow(Integer ownerId, BigDecimal counts, FlowSource fundsSource, FlowType fundsChangeType, Integer referId, String code) {
        if (ownerId <= 0 || fundsSource == null || fundsChangeType == null)
            return;

        FmsFlow fmsFlow = new FmsFlow();
        fmsFlow.setType(fundsChangeType);
        fmsFlow.setSource(fundsSource);
        fmsFlow.setChange_num(counts);
        fmsFlow.setCreateTime(new Date());
        fmsFlow.setUserId(ownerId);
        fmsFlow.setReferCode(code);
        fmsFlowDao.add(fmsFlow);
    }

    public Boolean updateInventory(Integer id,FlowType flowType){
        SeckillGoods seckillGoods=seckillGoodsDao.getById(id);
        synchronized (seckillGoods) {
            //处理秒杀库存
            if (FlowType.Add.equals(flowType)) {
                seckillGoods.setInventory(seckillGoods.getInventory() + 1);
                if (seckillGoods.getSaleVolume()-1 <0)
                    return false;

                seckillGoods.setSaleVolume(seckillGoods.getSaleVolume()-1);
            }

            else if (FlowType.Reduce.equals(flowType)) {
                if (seckillGoods.getInventory() <=0)
                    return false;

                seckillGoods.setInventory(seckillGoods.getInventory()-1);
                seckillGoods.setSaleVolume(seckillGoods.getSaleVolume()+1);
            }

            seckillGoodsDao.modify(seckillGoods);

            return true;
        }

    }

}